// 自定义滚动条
import PerfectScrollbar from 'perfect-scrollbar';
// 对应的css
import 'perfect-scrollbar/css/perfect-scrollbar.css';

import { debounce } from '@/utils/index.js';
import { isMobile } from '@/utils/tools';

/**
  * 〖Author〗 MiWi.LIN ＾＾＾＾〖E-mail〗 80383585@qq.com
  * ======================================================== Copyright(c) 2021/4/28 ==
  * 〖Version〗 1.0 <BR/>
  * 〖Date〗 2021/4/28_8:52 PM <BR/>
  * 〖Desc〗 用于长列表底部在可见范围内显示滚动条，目前仅限页面中的最后一个table有效，因为el.querySelector('.el-table__body-wrapper')，使用方式：
 * <el-table
       v-table-fixed-scrollbar="{ bottom: 71 }" ... <BR/>
  * 〖Modify By〗 <BR/>
  */
const realUpdateScrollBar = debounce(() => { // 防抖
  if (!tableBodyWrapper) return;
  if (!railX) railX = tableBodyWrapper.querySelector('.ps__rail-x');
  // 如果table内部还有滚动条的话需要加上tableBodyWrapper.scrollTop
  const _top = window.innerHeight - tableBodyWrapper.getBoundingClientRect().top - railX.clientHeight;
  // console.log(window.innerHeight, tableBodyWrapper.getBoundingClientRect().top, railX.clientHeight, _top);
  railX.style.top = `${_top - marginBottom}px`;
  railX.style.opacity = '1';
  railX.style.display = 'block';
  railX.style.zIndex = '5';
}, 200);

const updateScrollBar = () => {
  if (!tableBodyWrapper) return;
  if (!railX) railX = tableBodyWrapper.querySelector('.ps__rail-x');
  // top为dom上侧距离可视窗口顶部的值
  const { bottom: tableBodyDomBottom } = tableBodyWrapper.getBoundingClientRect();

  if (railX.style.display !== 'none') railX.style.display = 'none';
  if (tableBodyDomBottom + marginBottom - scrollBarHeight <= window.innerHeight + scrollBarHeight) return; // 滚动到底部就不需要展示了
  realUpdateScrollBar();
};

const el_scrollBar = () => {
  if (tableBodyWrapper._ps_ instanceof PerfectScrollbar) {
    tableBodyWrapper._ps_.update();
  } else {
    tableBodyWrapper._ps_ = new PerfectScrollbar(tableBodyWrapper, {
      suppressScrollX: false,
      suppressScrollY: true // y方向禁止
    });
    // setTimeout(() => {
    //     tableBodyWrapper._ps_.update();
    // }, 17);
  }
};

const registerListener = () => {
  // 注册scroll和resize事件
  if (!_scrollHander) {
    _scrollHander = () => {
      if (!isScrolling) {
        window.requestAnimationFrame(() => {
          updateScrollBar();
          isScrolling = false;
        });
      }
      isScrolling = true;
    };
  }

  if (!_resizeHander) {
    _resizeHander = () => {
      updateScrollBar();
    };
  }
  document.removeEventListener('scroll', _scrollHander); // 避免重复绑定
  window.removeEventListener('resize', _resizeHander);
  document.addEventListener('scroll', _scrollHander); // 重新绑定
  window.addEventListener('resize', _resizeHander);
};

const scrollBarHeight = 15;
let isScrolling = false;
let _scrollHander = null;
let _resizeHander = null;
let marginBottom = 0;
let tableBodyWrapper = null;
let railX = null;

const directive = {
  bind(el, binding, vnode) {
    // console.info('FixedScroll bind');
    marginBottom = binding && binding.value.bottom || 0;
  },
  inserted(el) {
    // console.info('FixedScroll inserted');
    if (isMobile()) return; // 移动端不需要

    // 获取当前的table
    tableBodyWrapper = el.querySelector('.el-table__body-wrapper');
    railX = tableBodyWrapper.querySelector('.ps__rail-x');

    if (!tableBodyWrapper) {
      return console.warn('未发现className为el-table__body-wrapper的dom');
    }
    const rules = ['fixed', 'absolute', 'relative'];
    if (!rules.includes(window.getComputedStyle(tableBodyWrapper, null).position)) {
      console.error(`perfect-scrollbar所在的容器的position属性必须是以下之一：${rules.join('、')}`);
    }
    el_scrollBar();
    updateScrollBar();

    registerListener();
  },
  update(el, binding, vnode) {
    // console.info('FixedScroll update');
    marginBottom = binding && binding.value.bottom || 0;
  },
  componentUpdated(el, binding, vnode) {
    // console.info('FixedScroll componentUpdated');
    const {
      expression
    } = binding;

    // 获取当前的table
    tableBodyWrapper = el.querySelector('.el-table__body-wrapper');
    railX = tableBodyWrapper.querySelector('.ps__rail-x');

    if (!tableBodyWrapper) {
      return console.warn('未发现className为el-table__body-wrapper的dom');
    }

    const handler = () => vnode.context[expression].apply();

    vnode.context.$nextTick(() => {
      try {
        el_scrollBar();
        updateScrollBar();
        if (expression) {
          handler();
        }
      } catch (error) {
        // console.error(`未找到该Fun：${expression}！`);
        // console.error('vnode', error);
      }
    });
    registerListener();
  },
  unbind() { // 需要指令绑定的组件通过v-if隐藏才会调用
    // console.info('FixedScroll unbind');
    document.removeEventListener('scroll', _scrollHander);
    window.removeEventListener('resize', _resizeHander);
    isScrolling = false;
    _scrollHander = null;
    _resizeHander = null;
    railX = null;
    tableBodyWrapper = null;
    marginBottom = 0;
  }
};

export default {}.install = (Vue, options = {}) => {
  Vue.directive('tableFixedScrollbar', directive);
};
